/*
     raw os - Copyright (C)  Lingjun Chen(jorya_txj).

    This file is part of raw os.

    raw os is free software; you can redistribute it it under the terms of the 
    GNU General Public License as published by the Free Software Foundation; 
    either version 3 of the License, or  (at your option) any later version.

    raw os is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
    without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program. if not, write email to jorya.txj@gmail.com
                                      ---

    A special exception to the LGPL can be applied should you wish to distribute
    a combined work that includes raw os, without being obliged to provide
    the source code for any proprietary components. See the file exception.txt
    for full details of how and when the exception can be applied.
*/


/* 	2012-10  Created by jorya_txj
  *	xxxxxx   please added here
  */
  

#include <raw_api.h>


#if (CONFIG_RAW_TASK_0 > 0)

/*
************************************************************************************************************************
*                                       Post an event to task 0
*
* Description: This function is called to post an event to task 0
*
* Arguments  : p is which event handler         
*                   ---------------------
*			ev is the event signal 
*                   ---------------------
*                   data is the event data
* Returns		
*						
* Note(s)     
*
*             
************************************************************************************************************************
*/	
void raw_task_0_post(EVENT_HANLDER *p, RAW_U8 ev, RAW_U8 *data)
{
	RAW_U32 snum;
	RAW_SR_ALLOC();

	
	if(nevents_points == MAX_TASK_EVENT) {
		RAW_ASSERT(0);
	}


	RAW_CPU_DISABLE();

	snum = (fevent_point + nevents_points) & (MAX_TASK_EVENT - 1);
	++nevents_points;

	if (task_0_is_ready == 0) {
		add_ready_list_end(&raw_ready_queue, &raw_interrupt_process_obj);
		task_0_is_ready = 1;
	}

	RAW_CPU_ENABLE();

	task_0_events_queue[snum].ev = ev;
	task_0_events_queue[snum].data = data;
	task_0_events_queue[snum].p = p;

	if (nevents_points > peak_events) {
		peak_events = nevents_points;
	}
	
 
}


static void task_0_process(void *pa)
{
	RAW_U8 ev;
	RAW_U8 *data;
	EVENT_HANLDER *receiver;
	RAW_U8 done;
	
	RAW_SR_ALLOC();
	
	while (1) {
		
		done = 0;
		
		while (done == 0) {
			
			RAW_CPU_DISABLE();
			
			if (nevents_points) {

				/* There are events that we should deliver. */
				ev = task_0_events_queue[fevent_point].ev;

				data = task_0_events_queue[fevent_point].data;
				receiver = task_0_events_queue[fevent_point].p;
			
				fevent_point = (fevent_point + 1) & (MAX_TASK_EVENT - 1);
				--nevents_points;
				RAW_CPU_ENABLE();

				receiver->handle_event(ev, data);
			}

			else {

				remove_ready_list(&raw_ready_queue, &raw_interrupt_process_obj);
				task_0_is_ready = 0;
				RAW_CPU_ENABLE();
		
				raw_sched();
				done = 1;
			}
			
		}
		
		
	}
		
}



/*
************************************************************************************************************************
*                                      Init task 0
*
* Description: This function is called to init task 0
*
* Arguments  :NONE   
*
* Returns		
*						
* Note(s)     
*
*             
************************************************************************************************************************
*/	
void raw_task_0_init()
{

	/*Create a timer task to handle soft timer*/
	raw_task_create(&raw_interrupt_process_obj, (RAW_U8  *)"timer_object",  0, 
	0,  0, task_0_stack, TASK_0_STACK_SIZE, task_0_process, 1);

}

#endif

